﻿#include <QCoreApplication>
#include <QDir>
#include <QRandomGenerator>
#include <QPainter>
#include "CCamerSdkOper.h"
#include "CGlobal.h"

CCamerSdkOper::CCamerSdkOper(CDevDataCam* pDevDataCam)
{
	m_pDevDataCam = pDevDataCam;
}

CCamerSdkOper::~CCamerSdkOper()
{
	for (auto it = m_cMapVlc.begin(); it != m_cMapVlc.end(); it++)
	{
		if (it.value() != nullptr)
		{
			delete it.value();
			it.value() = nullptr;
		}
	}
	//hjx++在退出时释放相关海康sdk资源
	if (m_pDevDataCam->m_sStruDeviceInfo.lLoginID != -1)
	{
		//注销用户
		NET_DVR_Logout(m_pDevDataCam->m_sStruDeviceInfo.lLoginID);
		//释放 SDK 资源
		NET_DVR_Cleanup();
	}
	m_cMapVlc.clear();
}

void CCamerSdkOper::setCorrectData(double dLeftRectifyValue, double dRightRectifyValue, int nRectifySetValue, int nRectifySetValueTwo, QPointF BeltEdgePf1, QPointF BeltEdgePf2, QPointF BeltEdgePf3, QPointF BeltEdgePf4, int nIsHaveBeltState, bool bBeltState)
{
	m_dLeftRectifyValue = dLeftRectifyValue;
	m_dRightRectifyValue = dRightRectifyValue;
	m_nRectifySetValue = nRectifySetValue;
	m_nRectifySetValueTwo = nRectifySetValueTwo;
	m_BeltEdgePf1 = BeltEdgePf1;
	m_BeltEdgePf2 = BeltEdgePf2;
	m_BeltEdgePf3 = BeltEdgePf3;
	m_BeltEdgePf4 = BeltEdgePf4;
	m_nIsHaveBeltState = nIsHaveBeltState;
	m_bBeltState = bBeltState;
	for (auto it = m_cMapVlc.begin(); it != m_cMapVlc.end(); it++)
	{
		it.value()->setCorrectData(dLeftRectifyValue, dRightRectifyValue, nRectifySetValue, nRectifySetValueTwo, BeltEdgePf1, BeltEdgePf2, BeltEdgePf3, BeltEdgePf4, nIsHaveBeltState, bBeltState);
	}
}

bool CCamerSdkOper::initAndLogin(QString &sReInfo)
{
	if (!m_pDevDataCam->m_bInit)
	{
		if (!initCamer(sReInfo))
		{
			return false;
		}
	}
	if (!m_pDevDataCam->m_bLogin)
	{
		if (!loginCamer(sReInfo))
		{
			m_pDevDataCam->m_bInit = false;
			m_pDevDataCam->m_bLogin = false;
			return false;
		}

	}
	return true;
}

bool CCamerSdkOper::initCamer(QString &sReInfo)
{
	if (NET_DVR_Init())
	{
		m_pDevDataCam->m_bInit = true;
		sReInfo = A2T("摄像头初始化成功");
		return true;
	}
	else
	{
		m_pDevDataCam->m_bInit = false;
		sReInfo = A2T("摄像头初始化失败，") + getErrMsg();
		return false;
	}
}

bool CCamerSdkOper::loginCamer(QString &sReInfo)
{
	if (m_pDevDataCam->m_bLogin)
	{
		return true;
	}
	NET_DVR_DEVICEINFO_V30 DeviceInfoTmp;
	memset(&DeviceInfoTmp, 0, sizeof(NET_DVR_DEVICEINFO_V30));
	char *cDeviceIp;
	char *cUserName;
	char *cPassWord;
	QByteArray ba1 = m_pDevDataCam->m_sCamerIp.toLatin1();
	cDeviceIp = ba1.data();
	QByteArray ba2 = m_pDevDataCam->m_sUserName.toLatin1();
	cUserName = ba2.data();
	QByteArray ba3 = m_pDevDataCam->m_sPassWord.toLatin1();
	cPassWord = ba3.data();
	//设置连接时间与重连时间
	int nProt = m_pDevDataCam->m_nCamerPort;
	LONG lLoginID = NET_DVR_Login_V30(cDeviceIp, nProt, cUserName, cPassWord, &DeviceInfoTmp);
	if (lLoginID == -1)
	{
		sReInfo = A2T("摄像头连接失败,") + getErrMsg();
		m_pDevDataCam->m_bLogin = false;
		return false;
	}
	else
	{
		m_pDevDataCam->m_sStruDeviceInfo.lLoginID = lLoginID;
		m_pDevDataCam->m_sStruDeviceInfo.iDeviceChanNum = DeviceInfoTmp.byChanNum;
		m_pDevDataCam->m_sStruDeviceInfo.iIPChanNum = DeviceInfoTmp.byIPChanNum;
		m_pDevDataCam->m_sStruDeviceInfo.iStartChan = DeviceInfoTmp.byStartChan;
		m_pDevDataCam->m_sStruDeviceInfo.iIPStartChan = DeviceInfoTmp.byStartDChan;
		m_pDevDataCam->m_bLogin = true;
		getDevCfg();                   //获取设备资源信息
		getDecoderCfg();               //获取摄像头解码器信息
		sReInfo = A2T("摄像头连接成功");
		return true;
	}
}

bool CCamerSdkOper::login(QString &sReInfo)
{
	return initAndLogin(sReInfo);
}

bool CCamerSdkOper::realPlay(int nDevId, WId hHand, QWidget *pWidget, QString &sReInfo)
{
	QString sRtspUrl = "";
	sRtspUrl = m_pDevDataCam->m_sRtspUrlImg;
	if (m_cMapVlc.contains(hHand))
	{
		sReInfo = A2T("视频RTSP正在预览");
		return true;
		if (m_cMapVlcState[hHand])
		{
			sReInfo = A2T("视频RTSP正在预览");
			return true;
		}
		else
		{
			bool bOk;
			CVlcOper* pVlcRtspOper = m_cMapVlc[hHand];
			QMetaObject::invokeMethod(QCoreApplication::instance(), [&bOk, pVlcRtspOper]()
			{
				bOk = pVlcRtspOper->startCapture();  // 在主线程执行
			}, Qt::BlockingQueuedConnection); // ⚠️ 阻塞调用，等待执行完成
			if (bOk)
			{
				sReInfo = A2T("视频RTSP预览成功");
				m_cMapVlcState[hHand] = true;
				return true;
			}
			else
			{
				sReInfo = A2T("视频RTSP预览失败");
				m_cMapVlcState[hHand] = false;
				return false;
			}
		}
	}
	else
	{
		bool bOk = false;
		CVlcOper*pVlcRtspOper = new CVlcOper(m_pDevDataCam, sRtspUrl);
		QMetaObject::invokeMethod(QCoreApplication::instance(), [&bOk, pWidget, pVlcRtspOper]()
		{
			pVlcRtspOper->setImageWidget(pWidget);
			bOk = pVlcRtspOper->startCapture();  // 在主线程执行
		}, Qt::BlockingQueuedConnection); // ⚠ 阻塞调用，等待执行完成
		if (bOk)
		{
			sReInfo = A2T("视频RTSP预览成功");
			m_cMapVlc.insert(hHand, pVlcRtspOper);
			m_cMapVlcState.insert(hHand, true);
			return true;
		}
		else
		{
			sReInfo = A2T("视频RTSP预览失败");
			pVlcRtspOper->deleteLater();
			pVlcRtspOper = nullptr;
			return false;
		}
	}
}

bool CCamerSdkOper::stopRealPlay(WId hHand, QString &sReInfo)
{
	if (m_cMapVlc.contains(hHand))
	{
		bool bOk = false;
		CVlcOper* pVlcRtspOper = m_cMapVlc[hHand];
		QMetaObject::invokeMethod(QCoreApplication::instance(), [&bOk, pVlcRtspOper]()
		{
			bOk = pVlcRtspOper->stopCapture();
		}, Qt::BlockingQueuedConnection); // ⚠ 阻塞调用，等待执行完成
		if (bOk)
		{
			m_cMapVlcState[hHand] = false;
			delete pVlcRtspOper;
			m_cMapVlc[hHand] = nullptr;
		}
		m_cMapVlc.remove(hHand);
		sReInfo = A2T("关闭视频预览");
		return true;
	}
	else
	{
		sReInfo = A2T("关闭视频预览");
		return true;
	}
}

bool CCamerSdkOper::capture(int nDevId, QString &sPath, QString &sReInfo)
{
	if (nDevId == enCamer)
	{
		return captureImg(sPath, sReInfo);
	}
	else
	{
		return captureIr(sPath, sReInfo);
	}
}

bool CCamerSdkOper::getImage(QString &sPath, QString &sReInfo)
{
	return captureImgEx(sPath, sReInfo);
}

void CCamerSdkOper::getDevCfg()
{
	NET_DVR_IPPARACFG_V40 IpAccessCfg;
	memset(&IpAccessCfg, 0, sizeof(IpAccessCfg));
	DWORD  dwReturned;
	m_pDevDataCam->m_sStruDeviceInfo.bIPRet = NET_DVR_GetDVRConfig(m_pDevDataCam->m_sStruDeviceInfo.lLoginID, NET_DVR_GET_IPPARACFG_V40, 0, &IpAccessCfg, sizeof(NET_DVR_IPPARACFG_V40), &dwReturned);
	if (!m_pDevDataCam->m_sStruDeviceInfo.bIPRet)   //不支持ip接入,9000以下设备不支持禁用模拟通道
	{
		for (int i = 0; i < MAX_ANALOG_CHANNUM; i++)
		{
			if (i < m_pDevDataCam->m_sStruDeviceInfo.iDeviceChanNum + 1)
			{
				m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i].iChanIndex = i + m_pDevDataCam->m_sStruDeviceInfo.iStartChan;  //通道号
				m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i].bEnable = TRUE;

			}
			else
			{
				m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i].iChanIndex = -1;
				m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i].bEnable = FALSE;
			}
		}
	}
	else        //支持IP接入，9000设备
	{
		for (int i = 0; i < MAX_ANALOG_CHANNUM; i++)  //模拟通道
		{
			if (i < m_pDevDataCam->m_sStruDeviceInfo.iDeviceChanNum)
			{
				m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i].iChanIndex = i + m_pDevDataCam->m_sStruDeviceInfo.iStartChan;
				if (IpAccessCfg.byAnalogChanEnable[i])
				{
					m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i].bEnable = TRUE;
				}
				else
				{
					m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i].bEnable = FALSE;
				}

			}
			else//clear the state of other channel
			{
				m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i].iChanIndex = -1;
				m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i].bEnable = FALSE;
			}
		}
		//数字通道
		for (int i = 0; i < MAX_IP_CHANNEL; i++)
		{
			if (IpAccessCfg.struStreamMode[i].uGetStream.struChanInfo.byEnable)  //ip通道在线
			{
				m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i + MAX_ANALOG_CHANNUM].bEnable = TRUE;
				m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i + MAX_ANALOG_CHANNUM].iChanIndex = i + IpAccessCfg.dwStartDChan;

			}
			else
			{
				m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i + MAX_ANALOG_CHANNUM].bEnable = FALSE;
				m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i + MAX_ANALOG_CHANNUM].iChanIndex = -1;
			}
		}
	}
	m_pDevDataCam->m_cMapCamerInfo[enCamer].m_cClientInfo.lChannel = m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[0].iChanIndex;
	m_pDevDataCam->m_cMapCamerInfo[enIR].m_cClientInfo.lChannel = m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[1].iChanIndex;
}

void CCamerSdkOper::getDecoderCfg()
{
	NET_DVR_DECODERCFG_V30 DecoderCfg;
	DWORD  dwReturned;
	BOOL bRet;
	//获取通道解码器信息
	for (int i = 0; i < MAX_CHANNUM_V30; i++)
	{
		if (m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i].bEnable)
		{
			memset(&DecoderCfg, 0, sizeof(NET_DVR_DECODERCFG_V30));
			bRet = NET_DVR_GetDVRConfig(m_pDevDataCam->m_sStruDeviceInfo.lLoginID, NET_DVR_GET_DECODERCFG_V30, \
				m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i].iChanIndex, &DecoderCfg, sizeof(NET_DVR_DECODERCFG_V30), &dwReturned);
			if (!bRet)
			{
				continue;
			}
			memcpy(&m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[i].struDecodercfg, &DecoderCfg, sizeof(NET_DVR_DECODERCFG_V30));
		}
	}
}

bool CCamerSdkOper::captureIr(QString &sPath, QString &sReInfo)
{
	if (!initAndLogin(sReInfo))
	{
		return false;
	}
	LONG lLoginID = m_pDevDataCam->m_sStruDeviceInfo.lLoginID;
	LONG lChannel = m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[1].iChanIndex;     //0是可见光 1是红外
	NET_DVR_JPEGPARA JpgPara = { 0 };
	JpgPara.wPicSize = 0xff;
	JpgPara.wPicQuality = 0;
	sPath = sPath + QDateTime::currentDateTime().toString("yyyyMM") + "/" + QDateTime::currentDateTime().toString("dd") + "/";
	QDir folder(sPath);// 创建QDir对象
	if (!folder.exists())
	{
		// 文件夹不存在，则创建
		if (folder.mkpath("."))
		{
		}
	}
	// 创建随机数生成器
	QRandomGenerator *generator = QRandomGenerator::global();
	// 生成两位随机数
	int randomNum = generator->bounded(90) + 10; // 生成范围 [10, 99]
	QString sPathData = sPath + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz") + QString::number(randomNum) + ".data";
	sPath = sPath + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz") + QString::number(randomNum) + ".jpg";
	char *cRecNameData;
	QByteArray ba1 = sPathData.toLatin1();
	cRecNameData = ba1.data();
	NET_DVR_JPEGPICTURE_WITH_APPENDDATA struJpegPictureWithAppendAata = { 0 };
	char szLan[256] = { 0 };
	if (struJpegPictureWithAppendAata.pJpegPicBuff == NULL)
	{
		struJpegPictureWithAppendAata.pJpegPicBuff = new char[2 * 1024 * 1024];
		memset(struJpegPictureWithAppendAata.pJpegPicBuff, 0, 2 * 1024 * 1024);
	}
	if (struJpegPictureWithAppendAata.pP2PDataBuff == NULL)
	{
		struJpegPictureWithAppendAata.pP2PDataBuff = new char[2 * 1024 * 1024];
		memset(struJpegPictureWithAppendAata.pP2PDataBuff, 0, 2 * 1024 * 1024);
	}

	if (struJpegPictureWithAppendAata.pVisiblePicBuff == NULL)//可见光图至少为4M
	{
		struJpegPictureWithAppendAata.pVisiblePicBuff = new char[10 * 1024 * 1024];
		memset(struJpegPictureWithAppendAata.pVisiblePicBuff, 0, 10 * 1024 * 1024);
	}
	if (NET_DVR_CaptureJPEGPicture_WithAppendData(lLoginID, lChannel, &struJpegPictureWithAppendAata))
	{
		if (struJpegPictureWithAppendAata.dwP2PDataLen > 0 && struJpegPictureWithAppendAata.pP2PDataBuff != NULL)
		{
			/*char cFilenameData[256] = { 0 };
			memcpy(cFilenameData, cRecNameData, 256*sizeof(char));*/
			sReInfo += A2T("测温数据采集成功");
			DWORD dwWrittenBytesData = 0;
			HANDLE hFileData = CreateFileA(cRecNameData, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
			if (hFileData != INVALID_HANDLE_VALUE)
			{
				DWORD dwRet = WriteFile(hFileData, struJpegPictureWithAppendAata.pP2PDataBuff, struJpegPictureWithAppendAata.dwP2PDataLen, &dwWrittenBytesData, NULL);
				if (dwRet == 0 || dwWrittenBytesData < struJpegPictureWithAppendAata.dwP2PDataLen)
				{
					DWORD dwError = GetLastError();
				}
				delete struJpegPictureWithAppendAata.pJpegPicBuff;
				delete struJpegPictureWithAppendAata.pP2PDataBuff;
				delete struJpegPictureWithAppendAata.pVisiblePicBuff;
				CloseHandle(hFileData);
				hFileData = NULL;
			}
			NET_DVR_JPEGPARA JpgPara = { 0 };
			JpgPara.wPicSize = 0xff;
			JpgPara.wPicQuality = 0;
			char *cRecName;
			QByteArray ba = sPath.toLatin1();
			cRecName = ba.data();
			if (NET_DVR_CaptureJPEGPicture(lLoginID, lChannel, &JpgPara, cRecName))
			{
				sReInfo += A2T("红外测温图片抓取成功");
				return true;
			}
			else
			{
				sReInfo += A2T("红外测温图片抓取失败") + getErrMsg();
				return false;
			}
		}
		return true;
	}
	else
	{
		delete struJpegPictureWithAppendAata.pJpegPicBuff;
		delete struJpegPictureWithAppendAata.pP2PDataBuff;
		delete struJpegPictureWithAppendAata.pVisiblePicBuff;
		sReInfo += A2T("测温数据采集失败") + getErrMsg();
		return false;
	}
}

bool CCamerSdkOper::captureImg(QString &sPath, QString &sReInfo)
{
	NET_DVR_JPEGPARA JpgPara = { 0 };
	JpgPara.wPicSize = 0xff;
	JpgPara.wPicQuality = 0;
	sPath = sPath + QDateTime::currentDateTime().toString("yyyyMM") + "/" + QDateTime::currentDateTime().toString("dd") + "/";
	QDir folder(sPath);// 创建QDir对象
	if (!folder.exists())
	{
		// 文件夹不存在，则创建
		if (folder.mkpath("."))
		{
		}
	}
	// 创建随机数生成器
	QRandomGenerator *generator = QRandomGenerator::global();
	// 生成两位随机数
	int randomNum = generator->bounded(90) + 10; // 生成范围 [10, 99]

	sPath = sPath + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz") + QString::number(randomNum) + ".jpg";
	char *cRecName;
	QByteArray ba = sPath.toLatin1();
	cRecName = ba.data();
	LONG lLoginID = m_pDevDataCam->m_sStruDeviceInfo.lLoginID;
	LONG lChannel = m_pDevDataCam->m_sStruDeviceInfo.struChanInfo[0].iChanIndex;     //0是可见光 1是红外
	if (NET_DVR_CaptureJPEGPicture(lLoginID, lChannel, &JpgPara, cRecName))
	{
		sReInfo += A2T("可见光图片抓取成功");
		return true;
	}
	else
	{
		sReInfo += A2T("可见光图片抓取失败");
		return false;
	}
}

bool CCamerSdkOper::captureImgEx(QString &sPath, QString &sReInfo)
{
	NET_DVR_JPEGPARA JpgPara = { 0 };
	JpgPara.wPicSize = 0;
	JpgPara.wPicQuality = 0;
	// 分配缓冲区用于存储抓取的图像数据
	DWORD dwPicBufSize = 1024 * 1024; // 1MB 缓冲区
	char* lpPicBuf = new char[dwPicBufSize];
	memset(lpPicBuf, 0, 1024 * 1024);
	if (lpPicBuf == nullptr)
	{
		sReInfo += A2T("分配内存失败");
		return false;
	}

	DWORD dwBytesReturned = 0;
	sPath = sPath + QDateTime::currentDateTime().toString("yyyyMM") + "/" + QDateTime::currentDateTime().toString("dd") + "/";
	QDir folder(sPath);// 创建QDir对象
	if (!folder.exists())
	{
		// 文件夹不存在，则创建
		if (folder.mkpath("."))
		{
		}
	}
	// 创建随机数生成器
	QRandomGenerator *generator = QRandomGenerator::global();
	// 生成两位随机数
	int randomNum = generator->bounded(90) + 10; // 生成范围 [10, 99]

	sPath = sPath + QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss-zzz") + QString::number(randomNum) + ".jpg";
	char *cRecName;
	QByteArray ba = sPath.toLatin1();
	cRecName = ba.data();
	LONG lLoginID = m_pDevDataCam->m_sStruDeviceInfo.lLoginID;
	if (NET_DVR_CaptureJPEGPicture_NEW(lLoginID, 1, &JpgPara, lpPicBuf, dwPicBufSize, &dwBytesReturned))
	{
		sReInfo += A2T("可见光图片抓取成功");
	}
	else
	{
		sReInfo += A2T("可见光图片抓取失败") + getErrMsg();
		delete[] lpPicBuf;
		lpPicBuf = nullptr;
		return false;
	}
	// 如果抓取成功，解析图像数据
	QByteArray imageData = QByteArray((const char*)lpPicBuf, dwBytesReturned);
	QImage image;
	if (image.loadFromData(imageData))
	{
		// 处理图像
		drawRollerRealign(image);
		image.save(sPath);
	}
	else
	{
		sReInfo += A2T("图像转换失败");
		delete[] lpPicBuf;
		lpPicBuf = nullptr;
		return false;
	}
	// 释放缓冲区
	delete[] lpPicBuf;
	lpPicBuf = nullptr;
	return true;
}

QString CCamerSdkOper::getErrMsg()
{
	QString sErr = A2T("错误原因：");
	DWORD err = NET_DVR_GetLastError();
	sErr += A2T("错误码:%1").arg(err);
	switch (err)
	{
	case 0:
		sErr += A2T("没有错误。");
		break;
	case 1:
		sErr += A2T("用户名密码错误。注册时输入的用户名或者密码错误。");
		break;
	case 2:
		sErr += A2T("权限不足。一般和通道相关，例如有预览通道1权限，无预览通道2权限，即有预览权限但不完全，预览通道2返回此错误。");
		break;
	case 3:
		sErr += A2T("SDK未初始化。必须先调用NET_DVR_Init，该接口是调用其他SDK函数的前提且一个程序进程只需要调用一次。");
		break;
	case 4:
		sErr += A2T("通道号错误。设备通道分模拟通道和数字通道（IP通道），NET_DVR_Login_V40登录设备成功之后会返回设备支持的通道个数和起始通道号取值，详见“通道和通道号号相关说明”。");
		break;
	case 5:
		sErr += A2T("设备总的连接数超过最大。例如网络摄像机只支持6路预览，预览第7路即会返回失败，错误码返回5。不同设备性能不一样，支持路数也不同。");
		break;
	case 6:
		sErr += A2T("版本不匹配。SDK和设备的版本不匹配。");
		break;
	case 7:
		sErr += A2T("连接设备失败。设备不在线或网络原因引起的连接超时等。");
		break;
	case 8:
		sErr += A2T("向设备发送失败。");
		break;
	case 9:
		sErr += A2T("从设备接收数据失败。");
		break;
	case 10:
		sErr += A2T("从设备接收数据超时。");
		break;
	case 11:
		sErr += A2T("传送的数据有误。发送给设备或者从设备接收到的数据错误，如远程参数配置时输入设备不支持的值。");
		break;
	case 12:
		sErr += A2T("调用次序错误。");
		break;
	case 13:
		sErr += A2T("无此权限。用户对某个功能模块的权限，例如无预览权限用户预览返回此错误。");
		break;
	case 14:
		sErr += A2T("设备命令执行超时。");
		break;
	case 15:
		sErr += A2T("串口号错误。指定的设备串口号不存在。");
		break;
	case 16:
		sErr += A2T("报警端口错误。指定的设备报警输入或者输出端口不存在。");
		break;
	case 17:
		sErr += A2T("参数错误。SDK接口中给入的输入或输出参数为空，或者参数格式或值不符合要求。");
		break;
	case 18:
		sErr += A2T("设备通道处于错误状态");
		break;
	case 19:
		sErr += A2T("设备无硬盘。当设备无硬盘时，对设备的录像文件、硬盘配置等操作失败。");
		break;
	case 20:
		sErr += A2T("硬盘号错误。当对设备进行硬盘管理操作时，指定的硬盘号不存在时返回该错误。");
		break;
	case 21:
		sErr += A2T("设备硬盘满。");
		break;
	case 22:
		sErr += A2T("设备硬盘出错");
		break;
	case 23:
		sErr += A2T("设备不支持。");
		break;
	case 24:
		sErr += A2T("设备忙。");
		break;
	case 25:
		sErr += A2T("设备修改不成功。");
		break;
	case 26:
		sErr += A2T("密码输入格式不正确");
		break;
	case 27:
		sErr += A2T("硬盘正在格式化，不能启动操作。");
		break;
	case 28:
		sErr += A2T("设备资源不足。");
		break;
	case 29:
		sErr += A2T("设备操作失败。");
		break;
	case 30:
		sErr += A2T("语音对讲、语音广播操作中采集本地音频或打开音频输出失败。");
		break;
	case 31:
		sErr += A2T("设备语音对讲被占用。");
		break;
	case 32:
		sErr += A2T("时间输入不正确。");
		break;
	case 33:
		sErr += A2T("回放时设备没有指定的文件。");
		break;
	case 34:
		sErr += A2T("创建文件出错。本地录像、保存图片、获取配置文件和远程下载录像时创建文件失败。");
		break;
	case 35:
		sErr += A2T("打开文件出错。可能因为文件不存在或者路径错误。");
		break;
	case 36:
		sErr += A2T("上次的操作还没有完成。");
		break;
	case 37:
		sErr += A2T("获取当前播放的时间出错。");
		break;
	case 38:
		sErr += A2T("播放出错。");
		break;
	case 39:
		sErr += A2T("文件格式不正确。");
		break;
	default:
		sErr += A2T("其他错误。");
		break;
	}
	return sErr;
}

void CCamerSdkOper::drawRollerRealign(QImage& image)
{
	// 获取客户区的宽度和高度
	int clientWidth = image.width();;
	int clientHeight = image.height();
	QPainter painter(&image);

	// 根据状态选择画笔
	QPen leftPen = getPenForRectifyValue(m_dLeftRectifyValue*10, m_nRectifySetValueTwo, m_nRectifySetValue, m_nIsHaveBeltState);
	QPen rightPen = getPenForRectifyValue(m_dRightRectifyValue*10, m_nRectifySetValueTwo, m_nRectifySetValue, m_nIsHaveBeltState);

	// 画第一条线
	painter.setPen(leftPen);
	painter.drawLine(
		m_BeltEdgePf1.x() * clientWidth / 1920, m_BeltEdgePf1.y() * clientHeight / 1080,
		m_BeltEdgePf4.x() * clientWidth / 1920, m_BeltEdgePf4.y() * clientHeight / 1080
	);

	// 画第二条线
	painter.setPen(rightPen);
	painter.drawLine(
		m_BeltEdgePf2.x() * clientWidth / 1920, m_BeltEdgePf2.y() * clientHeight / 1080,
		m_BeltEdgePf3.x() * clientWidth / 1920, m_BeltEdgePf3.y() * clientHeight / 1080
	);

	// 设置文本颜色
	painter.setFont(QFont("SimSun", clientHeight*0.03, QFont::Bold));

	// 绘制左偏值文本
	QString strLeftValue = QString(A2T("左偏: %1 mm").arg(m_dLeftRectifyValue * 10, 0, 'f', 1));
	painter.setPen(leftPen);
	QRect rectLeftText(10, clientHeight*0.8, 300, 50);
	painter.drawText(rectLeftText, Qt::AlignLeft | Qt::AlignVCenter, strLeftValue);

	// 绘制右偏值文本
	QString strRightValue = QString(A2T("右偏: %1 mm").arg(m_dRightRectifyValue * 10, 0, 'f', 1));
	painter.setPen(rightPen);
	QRect rectRightText(10, clientHeight*0.9, 300, 50);
	painter.drawText(rectRightText, Qt::AlignLeft | Qt::AlignVCenter, strRightValue);
}

QPen CCamerSdkOper::getPenForRectifyValue(double rectifyValue, double setValueTwo, double setValue, int m_nHaveBeltState)
{
	// 设置画笔
	QPen greenPen(Qt::green, 4);
	QPen redPen(Qt::red, 4);
	QPen yellowPen(Qt::yellow, 4);
	QPen grayPen(Qt::gray, 4);

	if (m_nIsHaveBeltState != 0)
	{
		if (!m_bBeltState)
		{
			return grayPen;
		}
	}
	if (rectifyValue <= setValueTwo)
	{
		return redPen;
	}
	else if (rectifyValue > setValueTwo && rectifyValue <= setValue)
	{
		return yellowPen;
	}
	else
	{
		return greenPen;
	}
}
